﻿#define _CRT_SECURE_NO_WARNINGS 1

#include "string.h"
#include "list.h"
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <array>
using namespace std;

struct Point
{
	int _x;
	int _y;
};

//int main()
//{
//	int array1[] = { 1, 2, 3, 4, 5 };
//	int array2[5] = { 0 };
//	Point p = { 1, 2 };
//	return 0;
//}

//int main()
//{
//	int x1 = 1;
//	int x2{ 2 };
//
//	int array1[]{ 1, 2, 3, 4, 5 };
//	int array2[5]{ 0 };
//	Point p{ 1, 2 };
//
//	// C++11中列表初始化也可以适用于new表达式中
//	int* pa = new int[4] { 0 };
//	return 0;
//}

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

//int main()
//{
//	Date d1(2022, 1, 1); // old style
//
//	// C++11支持的列表初始化，这里会调用构造函数初始化
//	Date d2{ 2022, 1, 2 };
//	Date d3 = { 2022, 1, 3 };
//
//	return 0;
//}

//int main()
//{
//	// the type of il is an initializer_list 
//	auto il = { 10, 20, 30 };
//	cout << typeid(il).name() << endl;
//
//	return 0;
//}

//int main()
//{
//	vector<int> v = { 1,2,3,4 };
//	list<int> lt = { 1,2 };
//
//	// 这里{"sort", "排序"}会先初始化构造一个pair对象
//	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
//
//	// 使用大括号对容器赋值
//	v = { 10, 20, 30 };
//
//	return 0;
//}

namespace YC
{
	template<class T>
	class vector {
	public:
		typedef T* iterator;
		vector(initializer_list<T> l)
		{
			_start = new T[l.size()];
			_finish = _start + l.size();
			_endofstorage = _start + l.size();
			iterator vit = _start;
			typename initializer_list<T>::iterator lit = l.begin();
			while (lit != l.end())
			{
				*vit++ = *lit++;
			}
			//for (auto e : l)
			//   *vit++ = e;
		}
		vector<T>& operator=(initializer_list<T> l) {
			vector<T> tmp(l);
			std::swap(_start, tmp._start);
			std::swap(_finish, tmp._finish);
			std::swap(_endofstorage, tmp._endofstorage);
			return *this;
		}
	private:
		iterator _start;
		iterator _finish;
		iterator _endofstorage;
	};
}

//int main()
//{
//	const int x = 1;
//	double y = 1.1;
//
//	decltype(x * y) ret;
//	decltype(&x) p;
//	cout << typeid(ret).name() << endl;
//	cout << typeid(p).name() << endl;
//
//	return 0;
//}

//int main()
//{
//	array<int, 10> a1;
//	vector<int> a2(10, 0);
//
//	return 0;
//}

//int main()
//{
//	// 左值是一个表达式，可以取地址的
//	// 左值和右值，能否取地址
//	// 左值：可以取地址的
//	// 右值：不可以取地址的
//	int a = 10;
//	int b = a;
//	const int c = 10;
//	int* p = &a;
//	vector<int> v(10, 1);
//
//	cout << &a << endl;
//	cout << &b << endl;
//	cout << &c << endl;
//	cout << &(*p) << endl;
//	cout << &(v[1]) << endl;
//
//	return 0;
//}

//int main()
//{
//	//(取地址要求左值)
//	 //cout << &10 << endl;
//	 //cout << &string("1111") << endl;
//	 //cout << &to_string(123) << endl;
//
//
//	int x = 1, y = 2;
//	//cout << &(x + y) < endl;
//
//
//	// 右值引用，给右值取别名
//	// 纯右值 （内置类型的）
//	// 将亡值 （自定义类型的）
//	int&& rref1 = (x + y);
//	string&& rref2 = string("1111");
//	string&& rref3 = to_string(123);
//	int&& rref4 = 10;
//
//	// 左值引用能否给右值取别名 -- 不可以，但是const左值引用可以
//	const string& ref1 = string("1111");
//	const int& ref2 = 10;
//
//	// 右值引用能否给左值取别名 -- 不可以，但是可以给move以后的左值取别名
//	string s1("1111");
//	string&& rref5 = move(s1);
//
//	return 0;
//}

//int main()
//{
//	//YC::string ret1;
//	//ret1 = YC::to_string(1234);
//
//	//YC::string ret2 = YC::to_string(1234);
//	//cout << ret2.c_str() << endl;
//
//	std::string s1("11111111111111111111111");
//	std::string s2 = s1;
//	std::string s3 = move(s1);
//
//	return 0;
//}

//int main()
//{
//	std::string s3("22222222222");
//	// 左值引用
//	std::string& s4 = s3;
//	cout << &s4 << endl;
//
//	// 右值引用
//	std::string&& s1 = std::string("111111111");
//	// s1是左值（右值引用本身是左值）
//	cout << &s1 << endl;
//	//cout << &std::string("111111111") << endl;
//
//	std::string& s5 = s1;
//
//	std::string&& s6 = std::string("111111111111111111111111111111111111111");
//	std::string& s7 = s6;
//
//	return 0;
//}


#include"list.h"

//int main()
//{
//	YC::list<YC::string> lt;               // 构造 + 拷贝构造  主要体现在ListNode初始化那里
//	cout << "*************************" << endl << endl; 
//
//	YC::string s1("1111");
//	// 这里调用的是拷贝构造
//	lt.push_back(s1);         // 构造 + 拷贝构造
//	cout << endl;
//
//	// 这里调用的是移动构造
//	lt.push_back(YC::string("22222"));     // 构造 + 移动构造
//	//lt.push_back("22222");
//
//
//	// 上面效率提升，针对的是自定义类型的深拷贝的类，因为深拷贝的类才有转移资源的移动系列函数
//	// 对于内置类型，和浅拷贝自定义类型，没有移动系列函数
//	YC::list<int> lt1;
//	lt1.push_back(10);
//
//	int x = 20;
//	lt1.push_back(x);
//
//	return 0;
//}

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }

void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

// 右值引用，引用后，右值引用本身属性变成左值
// std::forward<T>(t)在传参的过程中保持了t的原生类型属性。

// 函数模版里面，这里可以叫万能引用
// 实参传左值，就推成左值引用
// 实参传右值，就推成右值引用
template<typename T>
void PerfectForward(T&& t)
{
	//Fun((T&&)t);
	Fun(forward<T>(t));   // 完美转发，目的是将函数参数在传递过程中保持其原始的类型和值类别
}

//void PerfectForward(int&& t)
//{
//	Fun((int&&)t);
//}
//
//void PerfectForward(int& t)
//{
//	Fun((int&)t);
//}
//
//void PerfectForward(const int&& t)
//{
//	Fun((const int&&)t);
//}
//
//void PerfectForward(const int& t)
//{
//	Fun((const int&)t);
//}

//int main()
//{
//	PerfectForward(10);           // 右值
//
//	int a;
//	PerfectForward(a);            // 左值
//	PerfectForward(std::move(a)); // 右值
//
//	const int b = 8;
//	PerfectForward(b);		      // const 左值
//	PerfectForward(std::move(b)); // const 右值
//
//	return 0;
//}

/////////////////////////////////////////////////////////////////////

#include<algorithm>

struct Goods
{
	string _name; // 名字
	double _price; // 价格
	int _evaluate; // 评价
	// ...

	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

struct ComparePriceLess
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price < gr._price;
	}
};

struct ComparePriceGreater
{
	bool operator()(const Goods& gl, const Goods& gr)
	{
		return gl._price > gr._price;
	}
};

//int main()
//{
//	vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,
//3 }, { "菠萝", 1.5, 4 } };
//
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//	
//	auto priceLess = [](const Goods& g1, const Goods& g2)
//	{
//		return g1._price < g2._price;
//	};
//
//	sort(v.begin(), v.end(), priceLess);
//
//	//cout << typeid(priceLess).name() << endl;
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) 
//		{
//			return g1._price > g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)
//		{
//			return g1._evaluate < g2._evaluate;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2)
//		{
//			return g1._evaluate > g2._evaluate;
//		});
//
//	return 0;
//}

//int main()
//{
//	// lambda
//	auto add1 = [](int a, int b)->int {return a + b; };
//
//	// 返回值可以省略
//	auto add2 = [](int a, int b) {return a + b; };
//
//	// 没有参数，参数列表可以省略
//	auto func1 = [] {cout << "hello world" << endl; };
//
//	cout << typeid(add1).name() << endl;
//	cout << typeid(add2).name() << endl;
//	cout << typeid(func1).name() << endl;
//
//	cout << add1(1, 2) << endl;
//	func1();
//
//	return 0;
//}

//int main()
//{
//	int a = 1, b = 2, c = 3, d = 4, e = 5;
//	cout << a << b << c << d << e << endl;
//
//	auto func1 = [&]()
//	{
//		a++;
//		b++;
//		c++;
//		d++;
//		e++;
//	};
//
//	func1();
//	cout << a << b << c << d << e << endl;
//
//	auto func2 = [=]()
//	{
//		;
//	};
//
//	auto func3 = [&, d, e]()
//	{
//		a++;
//		b++;
//		c++;
//
//		//d++;
//		//e++;
//	};
//	func3();
//	cout << a << b << c << d << e << endl;
//
//	auto func4 = [&, d, e]() mutable
//	{
//		a++;
//		b++;
//		c++;
//
//		d++;
//		e++;
//	};
//	func4();
//	cout << a << b << c << d << e << endl;
//
//	return 0;                                                     
//}

class Person
{
public:
	Person(const char* name = "李四", int age = 0)
		:_name(name)
		, _age(age)
	{}

	//~Person()
	//{}

private:
	YC::string _name;
	int _age;
};
//int main()
//{
//	Person s1;
//	Person s2 = s1; // 拷贝构造
//
//	Person s3 = std::move(s1); // 移动构造
//
//	Person s4;
//	s4 = std::move(s2); // 移动赋值
//	return 0;
//}

//int main()
//{
//	list<YC::string> It;
//
//	YC::string s1("xxxxxxxx");
//	It.push_back(s1);
//	It.push_back(move(s1));
//
//	cout << endl;
//
//	YC::string s2("xxxxxxxx");
//	It.emplace_back(s2);
//	It.emplace_back(move(s2));
//
//	return 0;
//}

// 这个类只能在堆上生成对象
class HeapOnly
{
public:
	static HeapOnly* CreateObj()
	{
		return new HeapOnly;
	}

	// C++11
	HeapOnly(const HeapOnly& hol) = delete;

private:
	// C++98 私有+只声明不实现
	//HeapOnly(const HeapOnly& hol);

	HeapOnly()
	{}

	int _a = 1;
};

//int main()
//{
//	// 不能直接构造对象
//	//HeapOnly hol;
//	//HeapOnly* p1 = new HeapOnly;
//
//	HeapOnly* p2 = HeapOnly::CreateObj();
//
//	// 拷贝构造也应当禁止，不然还能到栈上生成
//	//HeapOnly obj(*p2);
//
//	return 0;
//}

//template <class ...Args>
//void Cpp_printf(Args... args)
//{
//	cout << sizeof...(args) << endl; // 可以计算参数包的数据个数
//
//	//“args”: 必须在此上下文中扩展参数包
//	/*for (size_t i = 0; i < sizeof...(args); i++)
//	{
//		cout << args[i] << endl;
//	}
//	cout << endl;*/
//}

//int main()
//{
//	Cpp_printf(1);
//	Cpp_printf(1, 'A');
//	Cpp_printf(1, 'A', std::string("algorithm"));
//
//	return 0;
//}

//void _Cpp_Printf()
//{
//	cout << endl;
//}
//
//template<class T, class ...Args>
//void _Cpp_Printf(const T& val, Args... args)
//{
//	cout << val << endl;
//
//	_Cpp_Printf(args...);
//}
//
//template<class ...Args>
//void Cpp_Printf(Args... args)
//{
//	_Cpp_Printf(args...);
//}

//int main()
//{
//	Cpp_Printf(1);
//	Cpp_Printf(1, 'A');
//	Cpp_Printf(1, 'A', std::string("algorithm"));
//
//	return 0;
//}



/////////////////////////////////////////////////////////
//template <class T>
//int PrintArg(T t)
//{
//	cout << t << " ";
//	return 0;
//}
//
//template <class ...Args>
//void Cpp_Printf(Args... args)
//{
//	// 编译时推导，args...参数有几个值，PrintArg就调用几次，就有几个返回值，arr就开多大
//	int arr[] = { PrintArg(args)... };
//	cout << endl;
//}
//
////void Cpp_Printf(int x, char y, std::string z)
////{
////	int arr[] = { PrintArg(x),PrintArg(y),PrintArg(z) };
////	cout << endl;
////}
//
//int main()
//{
//	Cpp_Printf(1);
//	Cpp_Printf(1, 'A');
//	Cpp_Printf(1, 'A', std::string("algorithm"));
//
//	return 0;
//}

//int main()
//{
//	list<YC::string> It;
//
//	YC::string s1("xxxxxxxx");
//	It.push_back(s1);
//	It.push_back(move(s1));
//
//	cout << endl;
//
//	YC::string s2("xxxxxxxx");
//	It.emplace_back(s2);
//	It.emplace_back(move(s2));
//
//	return 0;
//}

//int main()
//{
//	// 没区别
//	YC::list<pair<YC::string, int>> lt;
//
//	pair<YC::string, int> kv1("xxxxx", 1);
//	//lt.push_back(kv1);
//	lt.push_back(move(kv1));
//
//	cout << endl;
//
//	// 直接传pair的对象效果跟push_back系列是一样的
//	pair<YC::string, int> kv2("xxxxx", 1);
//	lt.emplace_back(kv2);
//	lt.emplace_back(move(kv2));
//
//	cout << endl;
//
//	// 直接传构造pair的参数包，参数包一直往下传，底层直接构造
//	lt.emplace_back("xxxxx", 1);
//
//	return 0;
//}


////////////////////////////////////////////////////////////////////
#include<functional>

//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator()(int a, int b)
//	{
//		return a + b;
//	}
//};

// 不是定义可调用对象，包装可调用对象
//int main()
//{
//	function<int(int, int)> fc1;
//
//	//function<int(int, int)> fc2(f);
//	function<int(int, int)> fc2 = f;
//	function<int(int, int)> fc3 = Functor();
//	function<int(int, int)> fc4 = [](int x, int y) {return x + y;};
//
//	cout << fc2(1, 2) << endl;
//	//cout << fc2.operator()(1, 2) << endl;
//
//	cout << fc3(1, 2) << endl;
//	cout << fc4(1, 2) << endl;
//
//	return 0;
//}

template<class F, class T>
T useF(F f, T x)
{
	static int count = 0;
	cout << "count:" << ++count << endl;
	cout << "count:" << &count << endl;

	return f(x);
}

double f(double i)
{
	return i / 2;
}

struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};

//int main()
//{
//	// 函数名 函数指针
//	cout << useF(f, 11.11) << endl;
//
//	// 函数对象
//	cout << useF(Functor(), 11.11) << endl;
//
//	// lamber表达式
//	cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//
//	//////////////////////////
//	//////////////////////////
//	cout << endl;
//	cout << endl;
//
//	// 函数名 函数指针
//	function<double(double)> func1 = f;
//	cout << useF(func1, 11.11) << endl;
//
//	// 函数对象
//	function<double(double)> func2 = Functor();
//	cout << useF(func2, 11.11) << endl;
//
//	// lamber表达式
//	function<double(double)> func3 = [](double d)->double { return d / 4; };
//	cout << useF(func3, 11.11) << endl;
//
//	return 0;
//}

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};

//int main()
//{
//	// 成员函数的函数指针  &类型::函数名
//	function<int(int, int)> fc1 = &Plus::plusi;
//	cout << fc1(1, 2) << endl;
//
//	function<double(Plus*, double, double)> fc2 = &Plus::plusd;
//	Plus plus;
//	cout << fc2(&plus, 1.1, 2.2) << endl;
//
//	function<double(Plus, double, double)> fc3 = &Plus::plusd;
//	cout << fc3(Plus(), 1.1, 2.2) << endl;
//
//	return 0;
//}

////////////////////////////
///////////////////////////

//int Sub(int x, int y)
//{
//	return x - y;
//}

class Sub
{
public:
	Sub(int x)
		:_x(x)
	{}

	int sub(int a, int b)
	{
		return (a - b) * _x;
	}

private:
	int _x;
};

void fx(const string& name, int x, int y)
{
	cout << name << "->[" << "血量:" << x << ",蓝:" << y << ']' << endl;
}

template<class T>
void fy(int n)
{
	T* p = new T[n];
}

// 调整可调用对象的参数个数或者顺序
int main()
{
	//auto f1 = Sub;
	//cout << f1(10, 5) << endl;

	//// 调整顺序
	//auto f2 = bind(Sub, placeholders::_2, placeholders::_1);
	//cout << f2(10, 5) << endl;

	//cout << typeid(f1).name() << endl;
	//cout << typeid(f2).name() << endl;

	auto f3 = bind(&Sub::sub, placeholders::_1, placeholders::_2, placeholders::_3);
	cout << f3(Sub(1), 10, 5) << endl;

	Sub sub(1);
	cout << f3(&sub, 10, 5) << endl;

	// 绑定，调整参数个数
	auto f4 = bind(&Sub::sub, Sub(1), placeholders::_1, placeholders::_2);
	cout << f4(10, 5) << endl;

	auto f5 = bind(&Sub::sub, &sub, placeholders::_1, placeholders::_2);
	cout << f5(10, 5) << endl;

	/*fx("王昭君", 80, 20);
	fx("王昭君", 85, 10);
	fx("王昭君", 99, 0);
	fx("王昭君", 99, 80);

	fx("亚瑟", 99, 80);
	fx("亚瑟", 91, 80);
	fx("亚瑟", 5, 80);*/

	auto f6 = bind(fx, "王昭君", placeholders::_1, placeholders::_2);

	f6(80, 20);
	f6(85, 10);
	f6(99, 0);
	f6(99, 80);

	auto f7 = bind(fx, "亚瑟", placeholders::_1, placeholders::_2);

	f7(80, 20);
	f7(85, 10);
	f7(99, 0);
	f7(99, 80);

	//auto f8 = bind(fx, placeholders::_1, 80, placeholders::_2);
	function<void(std::string, int)> f8 = bind(fx, placeholders::_1, 80, placeholders::_2);
	f8("武则天", 50);
	f8("韩信", 40);

	cout << typeid(f7).name() << endl;
	cout << typeid(f8).name() << endl;

	map<string, function<int(int, int)>> opFuncMap = {
		   {"+", [](int a, int b) {return a + b; }},
		   {"-", bind(&Sub::sub, Sub(10), placeholders::_1, placeholders::_2)},
		   {"*", [](int a, int b) {return a * b; }},
		   {"/", [](int a, int b) {return a / b; }}
	};

	fy<int>(10);

	return 0;
}